#include "bpa.h"

bool callback(int percent, const char *str) {
  cout << "str: " << str << " " << percent << "%\n";
  return true;
}

BPA::BPA(double *vertice, double *normals, int vertice_num, double r)
{
    m.vn = vertice_num;
    MyMesh::VertexIterator vi = vcg::tri::Allocator<MyMesh>::AddVertices(m, vertice_num);
    for (int i=0;i<vertice_num;i++) {
        (*vi).P()[0] = vertice[i*3+0];
        (*vi).P()[1] = vertice[i*3+1];
        (*vi).P()[2] = vertice[i*3+2];
        (*vi).N()[0] = normals[i*3+0];
        (*vi).N()[1] = normals[i*3+1];
        (*vi).N()[2] = normals[i*3+2];
        vi++;
    }
    radius = r;
    clustering = 0.2;
}

int BPA::GetIndexVertex(MyMesh &m, MyMesh::VertexType *p)
{
    return p-&*(m.vert.begin());
}

void BPA::Reconstruction(int &face_num)
{
    vcg::tri::UpdateBounding<MyMesh>::Box(m);
    vcg::tri::UpdateNormal<MyMesh>::PerFace(m);
    printf("Input mesh  vn:%i fn:%i\n",m.VN(),m.FN());

    // Initialization
    tri::BallPivoting<MyMesh> pivot(m, radius, clustering);

    // the main processing
    pivot.BuildMesh(callback);

    printf("Ball radius: %f\nClustering points withing %f radii\n", pivot.radius, clustering);
    printf("Output mesh vn:%i fn:%i\n",m.VN(),m.FN());

    face_num = m.fn;
}

void BPA::CopyFaceIndex(int *faceIndex)
{
    MyMesh::FaceIterator fi;
    int i=0;
    for(fi=m.face.begin(); fi!=m.face.end(); ++fi, ++i) {
        faceIndex[3*i+0] = GetIndexVertex(m, (*fi).V(0));
        faceIndex[3*i+1] = GetIndexVertex(m, (*fi).V(1));
        faceIndex[3*i+2] = GetIndexVertex(m, (*fi).V(2));
    }
}
